<template>
  <view class="optimized-image" :style="containerStyle">
    <image 
      v-if="shouldLoad"
      :src="currentSrc"
      :mode="mode"
      :class="imageClass"
      :style="imageStyle"
      :show-menu-by-longpress="showMenuByLongpress"
      :lazy-load="lazyLoad"
      @load="onLoad"
      @error="onError"
      @click="onClick"
    />
    
    <!-- 占位符 -->
    <view v-else-if="placeholder" class="placeholder" :style="containerStyle">
      <image :src="placeholder" :mode="mode" class="placeholder-image" />
    </view>
    
    <!-- 加载状态 -->
    <view v-if="loading" class="loading-overlay">
      <u-loading-icon mode="flower" />
    </view>
    
    <!-- 错误状态 -->
    <view v-if="error && !loading" class="error-overlay" @click="retry">
      <u-icon name="image" size="32" color="#ccc" />
      <text class="error-text">加载失败，点击重试</text>
    </view>
  </view>
</template>

<script>
export default {
  name: 'OptimizedImage',
  props: {
    // 图片地址
    src: {
      type: String,
      required: true
    },
    // 占位图
    placeholder: {
      type: String,
      default: '/static/placeholder-device.png'
    },
    // 错误占位图
    errorImage: {
      type: String,
      default: '/static/placeholder-device.png'
    },
    // 图片模式
    mode: {
      type: String,
      default: 'aspectFill'
    },
    // 宽度
    width: {
      type: [String, Number],
      default: '100%'
    },
    // 高度
    height: {
      type: [String, Number],
      default: 'auto'
    },
    // 圆角
    borderRadius: {
      type: [String, Number],
      default: 0
    },
    // 是否懒加载
    lazyLoad: {
      type: Boolean,
      default: true
    },
    // 是否启用长按菜单
    showMenuByLongpress: {
      type: Boolean,
      default: false
    },
    // 压缩质量 (0-100)
    quality: {
      type: Number,
      default: 80
    },
    // 是否立即加载
    immediate: {
      type: Boolean,
      default: false
    }
  },
  
  data() {
    return {
      loading: false,
      error: false,
      shouldLoad: false,
      currentSrc: '',
      retryCount: 0,
      maxRetry: 3
    }
  },
  
  computed: {
    containerStyle() {
      return {
        width: typeof this.width === 'number' ? this.width + 'rpx' : this.width,
        height: typeof this.height === 'number' ? this.height + 'rpx' : this.height,
        borderRadius: typeof this.borderRadius === 'number' ? this.borderRadius + 'rpx' : this.borderRadius,
        position: 'relative',
        overflow: 'hidden',
        backgroundColor: '#f5f5f5'
      }
    },
    
    imageClass() {
      return {
        'optimized-image-main': true,
        'loading': this.loading
      }
    },
    
    imageStyle() {
      return {
        width: '100%',
        height: '100%',
        borderRadius: typeof this.borderRadius === 'number' ? this.borderRadius + 'rpx' : this.borderRadius
      }
    }
  },
  
  watch: {
    src: {
      handler(newSrc) {
        if (newSrc) {
          this.initImage()
        }
      },
      immediate: true
    }
  },
  
  methods: {
    initImage() {
      if (this.immediate) {
        this.loadImage()
      } else {
        // 延迟加载，可以配合IntersectionObserver使用
        this.shouldLoad = true
        this.loadImage()
      }
    },
    
    loadImage() {
      if (!this.src) return
      
      this.loading = true
      this.error = false
      
      // 处理图片压缩
      this.currentSrc = this.getOptimizedImageUrl(this.src)
      this.shouldLoad = true
    },
    
    getOptimizedImageUrl(url) {
      // 如果是本地图片或已经优化过的URL，直接返回
      if (!url || url.startsWith('/static/') || url.startsWith('data:') || url.includes('imageView2')) {
        return url
      }
      
      // 七牛云图片压缩参数
      if (url.includes('qiniu.com') || url.includes('clouddn.com')) {
        return `${url}?imageView2/2/w/800/h/800/q/${this.quality}`
      }
      
      // 阿里云OSS图片压缩
      if (url.includes('aliyuncs.com')) {
        return `${url}?x-oss-process=image/resize,w_800,h_800/quality,q_${this.quality}`
      }
      
      // 腾讯云COS图片压缩
      if (url.includes('myqcloud.com')) {
        return `${url}?imageView2/2/w/800/h/800/q/${this.quality}`
      }
      
      return url
    },
    
    onLoad(e) {
      this.loading = false
      this.error = false
      this.retryCount = 0
      this.$emit('load', e)
    },
    
    onError(e) {
      this.loading = false
      this.error = true
      console.warn('图片加载失败:', this.src, e)
      
      // 如果有错误占位图，显示它
      if (this.errorImage && this.currentSrc !== this.errorImage) {
        this.currentSrc = this.errorImage
        return
      }
      
      this.$emit('error', e)
    },
    
    retry() {
      if (this.retryCount < this.maxRetry) {
        this.retryCount++
        console.log(`重试加载图片 (${this.retryCount}/${this.maxRetry}):`, this.src)
        this.loadImage()
      } else {
        uni.showToast({
          title: '图片加载失败',
          icon: 'none'
        })
      }
    },
    
    onClick(e) {
      this.$emit('click', e)
    }
  }
}
</script>

<style lang="scss" scoped>
.optimized-image {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f5f5f5;
}

.optimized-image-main {
  width: 100%;
  height: 100%;
  
  &.loading {
    opacity: 0.8;
  }
}

.placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.placeholder-image {
  width: 100%;
  height: 100%;
  opacity: 0.3;
}

.loading-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10;
}

.error-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.05);
  z-index: 10;
}

.error-text {
  font-size: 24rpx;
  color: #999;
  margin-top: 16rpx;
  text-align: center;
}
</style> 